package org.ecbox.android.sdk.internal.stream;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.RejectedExecutionHandler;

import org.ecbox.android.sdk.Constants;
import org.ecbox.android.sdk.internal.stream.connect.HttpConnectionConfiguration;
import org.ecbox.android.sdk.internal.stream.message.MessageHandlerConfiguration;

/**
 * 客户端配置
 * 
 * File: Configuration.java<br/>
 * Description: <br/>
 * 
 * Copyright: Copyright (c) 2012 ecbox.com<br/>
 * Company: ECBOX,Inc.<br/>
 * 
 * @author chenxiaochun
 * @date 2013-1-1
 * @version 1.0
 */
public class Configuration implements HttpConnectionConfiguration, MessageHandlerConfiguration {

	private String connectUrl = "http://stream.api.ecbox.com/rest";// 连接地址
	private String signMethod = Constants.SIGN_METHOD_MD5;

	private int httpConnectionTimeout = 5;// 默认连接超时时间5s

	/*
	 * 由于服务端会间隔30s会发送一个心跳包，所以超时间比1分钟稍多点，使用者最好不要修改这个参数
	 */
	private int httpReadTimeout = 60 + 30;// 90s
	private int httpConnectRetryCount = 225;// 默认重试225次，如果每次连接的间隔在16s，那么默认尝试重连1个小时。
	private int httpConnectRetryInterval = 16;// 16s，如果连接失败，两次连接之间的间隔时间。
	private int sleepTimeOfServerInUpgrade = 5 * 60;// 当服务端在发布的时候休眠的时间，默认5分钟，
	private Map<String, String> reqHeader;

	/*
	 * 因为服务端目前在24小时后会断开连接，所以为了最低程度的降低消息丢失，在服务端断开之间客户端重连一次 默认是23小时加55分钟后自动重连
	 */
	private int httpReconnectInterval = (23 * 60 + 55) * 60;

	// 默认处理消息的线程池最小线程为10个
	private int minThreads = 5;
	private int maxThreads = 100;

	/*
	 * 假设每条消息为1k大小，队列里可以存大约50M的数据
	 */
	private int queueSize = 50000;

	/*
	 * 允许isv注入在消息处理线程出现RejectedExecutionException 后的处理方法。 默认使用AbortPolicy
	 */
	private RejectedExecutionHandler msgConsumeThreadPoolRejectHandler;

	private Set<EopCometStreamRequest> connectReqParam;

	/**
	 * 配置单连接<br/>
	 * 本长连接必须指定instanceUserId，也就是给具体应用实例使用的。
	 * 
	 * @param appKey
	 * @param secret
	 * @param instanceUserId
	 * @param accessToken
	 * @param connectionName
	 */
	public Configuration(String appKey, String secret, Long instanceUserId, String accessToken, String connectionName) {
		EopCometStreamRequest cometReq = new EopCometStreamRequest(appKey, secret, instanceUserId, accessToken,
				connectionName);
		// 设置签名方法
		connectReqParam = new HashSet<EopCometStreamRequest>(1);
		connectReqParam.add(cometReq);
	}

	/**
	 * 用于多连接
	 * 
	 * @param cometRequest
	 */
	public Configuration(Set<EopCometStreamRequest> cometRequest) {
		if (cometRequest == null || (cometRequest != null && cometRequest.size() == 0)) {
			throw new RuntimeException("comet request param is null");
		}
		this.connectReqParam = cometRequest;
	}

	// -----------http connection config
	public void setHttpConnectionTimeout(int httpConnectionTimeout) {
		this.httpConnectionTimeout = httpConnectionTimeout;
	}

	public int getHttpConnectionTimeout() {
		return httpConnectionTimeout;
	}

	public int getHttpReadTimeout() {
		return httpReadTimeout;
	}

	/**
	 * 由于服务端会间隔约30秒会发送一个心跳包，所以超时间比1分钟稍多点，使用者最好不要修改这个参数
	 * 
	 * @param httpReadTimeout
	 */
	public void setHttpReadTimeout(int httpReadTimeout) {
		this.httpReadTimeout = httpReadTimeout;
	}

	public void setHttpConnectRetryCount(int httpConnectRetryCount) {
		this.httpConnectRetryCount = httpConnectRetryCount;
	}

	public int getHttpConnectRetryCount() {
		return httpConnectRetryCount;
	}

	/**
	 * 方便测试使用，生成环境请不要调用此方法
	 * 
	 * @param connectUrl
	 */
	public void setConnectUrl(String connectUrl) {
		this.connectUrl = connectUrl;
	}

	public String getConnectUrl() {
		return connectUrl;
	}

	public void setHttpConnectRetryInterval(int httpConnectRetryInterval) {
		this.httpConnectRetryInterval = httpConnectRetryInterval;
	}

	public int getHttpConnectRetryInterval() {
		return httpConnectRetryInterval;
	}

	public void setSleepTimeOfServerInUpgrade(int sleepSecond) {
		this.sleepTimeOfServerInUpgrade = sleepSecond;
	}

	public int getSleepTimeOfServerInUpgrade() {
		return sleepTimeOfServerInUpgrade;
	}

	/*
	 * 因为服务端目前在24小时后会断开连接，所以为了最低程度的降低消息丢失，在服务端断开之间客户端重连一次(non-Javadoc)
	 */
	public void setHttpReconnectInterval(int httpReconnectInterval) {
		this.httpReconnectInterval = httpReconnectInterval;
	}

	public int getHttpReconnectInterval() {
		return httpReconnectInterval;
	}

	public void setRequestHeader(Map<String, String> reqHeader) {
		this.reqHeader = reqHeader;
	}

	public Map<String, String> getRequestHeader() {
		return reqHeader;
	}

	// ------------------http connection config end-
	// ------------------message factory config
	public void setMinThreads(int minThreads) {
		this.minThreads = minThreads;
	}

	public int getMinThreads() {
		return minThreads;
	}

	public void setMaxThreads(int maxThreads) {
		this.maxThreads = maxThreads;
	}

	public int getMaxThreads() {
		return maxThreads;
	}

	public void setQueueSize(int queueSize) {
		this.queueSize = queueSize;
	}

	public int getQueueSize() {
		return queueSize;
	}

	public RejectedExecutionHandler getMsgConsumeThreadPoolRejectHandler() {
		return msgConsumeThreadPoolRejectHandler;
	}

	public void setMsgConsumeThreadPoolRejectHandler(RejectedExecutionHandler msgConsumeThreadPoolRejectHandler) {
		this.msgConsumeThreadPoolRejectHandler = msgConsumeThreadPoolRejectHandler;
	}

	public void setSignMethd(String signMethod) {
		this.signMethod = signMethod;
	}

	public String getSignMethod() {
		return signMethod;
	}

	// --------message factory config end
	public Set<EopCometStreamRequest> getConnectReqParam() {
		return connectReqParam;
	}
}
